
package br.uff.probabilidade.applet;

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.Queue;
import java.util.Random;
import java.util.Stack;
import java.util.Vector;
import java.util.concurrent.DelayQueue;

import javax.swing.JOptionPane;

import br.uff.probabilidade.modelo.Conjunto;
import br.uff.probabilidade.modelo.Evento;
import br.uff.probabilidade.modelo.Imagem;
import br.uff.probabilidade.modelo.Legenda;
import br.uff.probabilidade.modelo.Marcador;
import br.uff.probabilidade.modelo.Operacao;
import br.uff.probabilidade.modelo.ParOrdenado;
import br.uff.probabilidade.modelo.Quadrado;
import br.uff.probabilidade.modelo.tabuleiro.Desafio;
import br.uff.probabilidade.modelo.tabuleiro.Grupamento;
import br.uff.probabilidade.modelo.tabuleiro.Nivel;
import br.uff.probabilidade.modelo.tabuleiro.Probabilidade;

import com.sun.org.apache.xerces.internal.dom.DOMOutputImpl;


/**
 * 
 * 
 * @poseidon-object-id [I875040m120ee925157mm7db9]
 */
public class Tabuleiro extends Atividade{
	
	private static final String IMAGE_DICE = "br/uff/probabilidade/imagens/dice";
	private static final int MAX_ERROS = 2;
	
	private static final int NUM_EVENTOS = 7;	
	
	public static final int QNT_EVENTOS = NUM_EVENTOS;//QNT a ser sorteada	
	
	private int contaValida = 0;

	public static final String IMAGE_CHECK = "br/uff/probabilidade/imagens/check.gif";
    public static final int ESPACO_COLUNAS = 80;
    public static final int ESPACO_LINHAS = 60;
    private boolean firstTime = true;       
   

/**
 * <p>Numero de Linhas do Tabuleiro</p>
 */
    private int numLinhas;

/**
 * <p>Numero de colunas do tabuleiro</p>
 */
    private int numColunas;
/**
 * <p>Eventos criados para o tabuleiro</p>
 */    
    
    private Evento[] eventos = new Evento[NUM_EVENTOS];
    
/**
 * <p></p>
 */
 
    
    private static final char[] NOMES_EVENTO={'A','B','C','D','E','F','G','H'};
    private static final char[] NOMES_OPERACAO={'W','Q','X','Y','K','Z'};
        
    
    private Vector desafios = new Vector();

/**
 * <p>Cria quadrados do tabuleiros. numLinhas X numColunas quadrados.</p>
 */
    
    private void criaDesafios(){
    	Desafio desafio = null;

    	//DESAFIO 1
    	desafio = new Desafio(4,this);
    	
    	desafio.setMensagemInicial("Veja a definição do evento A e selecione os resultados que pertencem a este evento, marcando" +
    			"a caixinha do quadrado correspondente. Cada clique marca ou desmarca a caixinha. Clique no" +
    			" botão CONFERIR ao terminar a marcação para conferir sua resposta ou no botão LIMPAR" +
    			" para recomeçar a marcação.");
    	
    	desafio.addEvento(this.eventos[0]);
    	desafio.addEvento(this.eventos[1]);
    	desafio.addEvento(this.eventos[2]);
    	desafio.addEvento(this.eventos[3]);
    	desafio.addEvento(this.eventos[4]);
    	desafio.addEvento(this.eventos[5]);
    	desafio.addEvento(this.eventos[6]);
    	desafio.sorteia();
    	
    	desafio.getNivel(0).setMensagemInicial("Boa sorte!");
    	desafio.getNivel(0).addEvento(desafio.getEventoSorteioAt(0));      	    	
    	desafio.getNivel(0).setPerguntaExpressao(false);
    	desafio.getNivel(0).setFormato(Nivel.FORMATO_DESCRICAO);
    	
    	desafio.getNivel(1).setMensagemInicial("Calcule as seguintes probabilidades, digitando os valores apropriados no" +
		"numerador e no denominador da fração abaixo!");    	
		desafio.getNivel(1).addHeranca(desafio.getNivel(0));    	
		desafio.getNivel(1).addProbabilidadeEventos(true);
		desafio.getNivel(1).setPerguntaExpressao(false);
		desafio.getNivel(1).setFormato(Nivel.FORMATO_DESCRICAO);
    	
    	desafio.getNivel(2).setMensagemInicial("Resolva o novo desafio!");
    	desafio.getNivel(2).addEvento(desafio.getEventoSorteioAt(1)); 
    	desafio.getNivel(2).setPerguntaExpressao(false);
    	desafio.getNivel(2).setFormato(Nivel.FORMATO_DESCRICAO);
    	
    	desafio.getNivel(3).setMensagemInicial("Calcule as seguintes probabilidades, digitando os valores apropriados no" +
    					"numerador e no denominador da fração abaixo!");    	
    	desafio.getNivel(3).addHeranca(desafio.getNivel(2));    	
    	desafio.getNivel(3).addProbabilidadeEventos(true);
    	desafio.getNivel(3).setPerguntaExpressao(false);
    	desafio.getNivel(3).setFormato(Nivel.FORMATO_DESCRICAO);
    	
    	this.desafios.add(desafio);
    	
    	//DESAFIO 2
    	desafio = new Desafio(2,this);    	    	
    	desafio.setMensagemInicial("Veja a definição dos eventos A e B e selecione os resultados que pertencem a cada um deles," +
    			"marcando a respectiva caixinha do quadrado correspondente. Cada clique marca ou desmarca" +
    			" a caixinha. Clique no botão CONFERIR ao terminar a marcação para conferir sua resposta ou" +
    			" no botão LIMPAR para recomeçar a marcação.");
    	
    	desafio.addEvento(this.eventos[0]);
    	desafio.addEvento(this.eventos[1]);
    	desafio.addEvento(this.eventos[2]);
    	desafio.addEvento(this.eventos[3]);
    	desafio.addEvento(this.eventos[4]);
    	desafio.addEvento(this.eventos[5]);
    	desafio.addEvento(this.eventos[6]);
    	desafio.sorteia();
    	
    	Grupamento grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(0));
    	grupamento.addEvento(desafio.getEventoAt(1));    	
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(1), Grupamento.OPERACAO_DIFERENCA);    	
    	desafio.addGrupamento(grupamento);
    	
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(0));
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(2), Grupamento.OPERACAO_DIFERENCA_REVERSO);
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(2), Grupamento.OPERACAO_DIFERENCA);
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(2), Grupamento.OPERACAO_UNIAO);
    	desafio.addGrupamento(grupamento);
    	
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(0));
    	grupamento.addEvento(desafio.getEventoAt(4));
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(4), Grupamento.OPERACAO_DIFERENCA_REVERSO);
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(4), Grupamento.OPERACAO_UNIAO);
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(4), Grupamento.OPERACAO_INTERSECAO);
    	desafio.addGrupamento(grupamento);
    	
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(0));
    	grupamento.addEvento(desafio.getEventoAt(5));
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(5), Grupamento.OPERACAO_DIFERENCA_REVERSO);    	
    	grupamento.addOperacao(desafio.getEventoAt(0), desafio.getEventoAt(5), Grupamento.OPERACAO_INTERSECAO);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(1));
    	grupamento.addEvento(desafio.getEventoAt(4));
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(4), Grupamento.OPERACAO_DIFERENCA_REVERSO);    	
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(4), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(4), Grupamento.OPERACAO_DIFERENCA);
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(4), Grupamento.OPERACAO_UNIAO);
    	desafio.addGrupamento(grupamento);
    	
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(1));
    	grupamento.addEvento(desafio.getEventoAt(5));
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(5), Grupamento.OPERACAO_DIFERENCA_REVERSO);    	
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(5), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(1), desafio.getEventoAt(5), Grupamento.OPERACAO_UNIAO);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(3));
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(3), Grupamento.OPERACAO_DIFERENCA_REVERSO);    	
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(3), Grupamento.OPERACAO_INTERSECAO);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(4));
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(4), Grupamento.OPERACAO_DIFERENCA_REVERSO);    	
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(4), Grupamento.OPERACAO_INTERSECAO);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(5)); 	
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(5), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(5), Grupamento.OPERACAO_DIFERENCA);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(6));	
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(6), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(2), desafio.getEventoAt(6), Grupamento.OPERACAO_UNIAO);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(3));
    	grupamento.addEvento(desafio.getEventoAt(5));  	
    	grupamento.addOperacao(desafio.getEventoAt(3), desafio.getEventoAt(5), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(3), desafio.getEventoAt(5), Grupamento.OPERACAO_DIFERENCA);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(3));
    	grupamento.addEvento(desafio.getEventoAt(6));
    	grupamento.addOperacao(desafio.getEventoAt(3), desafio.getEventoAt(6), Grupamento.OPERACAO_DIFERENCA_REVERSO);    	
    	grupamento.addOperacao(desafio.getEventoAt(3), desafio.getEventoAt(6), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(3), desafio.getEventoAt(6), Grupamento.OPERACAO_DIFERENCA);
    	grupamento.addOperacao(desafio.getEventoAt(3), desafio.getEventoAt(6), Grupamento.OPERACAO_UNIAO);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(4));
    	grupamento.addEvento(desafio.getEventoAt(5));   	
    	grupamento.addOperacao(desafio.getEventoAt(4), desafio.getEventoAt(5), Grupamento.OPERACAO_INTERSECAO);
    	grupamento.addOperacao(desafio.getEventoAt(4), desafio.getEventoAt(5), Grupamento.OPERACAO_DIFERENCA);
    	desafio.addGrupamento(grupamento);
    	
    	
    	desafio.getNivel(0).setPerguntaExpressao(true);
    	desafio.getNivel(0).setFormato(Nivel.FORMATO_DESCRICAO);
    	
    	desafio.getNivel(1).addHeranca(desafio.getNivel(0));
    	desafio.getNivel(1).setProbabilidadeOperacao(true);
    	desafio.getNivel(1).setFormato(Nivel.FORMATO_EXPRESSAO);
    	
    	final Evento eventoA = desafio.getEventoSorteioAt(0);    	    
    	
    	desafio.addEventoToNivel(eventoA,true, 0);
    		    		
    	
    	this.desafios.add(desafio);
    	
    	desafio = new Desafio(1,this);
    	desafio.setMensagemInicial("Não tem mensagem ainda!");
    	desafio.getNivel(0).setPerguntaExpressao(false);
    	desafio.getNivel(0).setProbabilidadeOperacao(true);
    	desafio.getNivel(0).setFormato(Nivel.FORMATO_EXPRESSAO);
    	
    	desafio.addEvento(this.eventos[0]);
    	desafio.addEvento(this.eventos[1]);
    	desafio.addEvento(this.eventos[2]);
    	desafio.addEvento(this.eventos[3]);
    	desafio.addEvento(this.eventos[4]);
    	desafio.addEvento(this.eventos[5]);
    	desafio.addEvento(this.eventos[6]);
    

    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(0));
    	grupamento.addEvento(desafio.getEventoAt(1));
    	grupamento.addEvento(desafio.getEventoAt(2)); 
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_UNIAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,true,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(true,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,true, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),1);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(3));
    	grupamento.addEvento(desafio.getEventoAt(6)); 
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_UNIAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,true,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(true,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,true, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),1);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(4));
    	grupamento.addEvento(desafio.getEventoAt(5)); 
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_UNIAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,true,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(true,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,true, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),1);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(2));
    	grupamento.addEvento(desafio.getEventoAt(5));
    	grupamento.addEvento(desafio.getEventoAt(6)); 
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_UNIAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,true,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(true,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,true, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),1);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(4));
    	grupamento.addEvento(desafio.getEventoAt(5));
    	grupamento.addEvento(desafio.getEventoAt(6)); 
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_UNIAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,true,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(true,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,true, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),1);
    	desafio.addGrupamento(grupamento);
    	
    	grupamento = new Grupamento();
    	grupamento.addEvento(desafio.getEventoAt(1));
    	grupamento.addEvento(desafio.getEventoAt(3));
    	grupamento.addEvento(desafio.getEventoAt(4)); 
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_UNIAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,true,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(true,grupamento.getEventoAt(0),Grupamento.OPERACAO_INTERSECAO,true, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),0);
    	grupamento.addOperacao(false,grupamento.getEventoAt(0),Grupamento.OPERACAO_UNIAO,false, grupamento.getEventoAt(1), Grupamento.OPERACAO_INTERSECAO,false,grupamento.getEventoAt(2),1);
    	desafio.addGrupamento(grupamento);

    	desafio.sorteia();
    	final Evento eventoB = desafio.getEventoSorteioAt(0);
    	desafio.addEventoToNivel(eventoB,true, 0);   
    	
    	this.desafios.add(desafio);    	    
    	
    }
    
    private Desafio getDesafioAtivo(){
    	for(int i=0;i<this.desafios.size();i++)
    		if(this.getDesafioAt(i).isAtivo())return this.getDesafioAt(i);
    	
    	return null;
    }
    
    
    public boolean validaDesafio(){
    	return this.getDesafioAtivo().isCompleto();
    }
    
    public boolean proximoDesafio(){
    	for(int i=0;i<this.desafios.size();i++){
    		if(this.getDesafioAt(i).isAtivo()){
    			this.getDesafioAt(i).setAtivo(false);
    			if(i+1<this.desafios.size()){
    				this.getDesafioAt(i+1).setAtivo(true);
    				this.getDesafioAt(i+1).inicia(new Imagem(this,this.getCodeBase(),IMAGE_CHECK));
    				return true;
    			}    			    		
    		}
    	}
    	if(this.desafios.size()>0 && this.getDesafioAt(0).isNew()){
    		this.getDesafioAt(0).setAtivo(true);
    		this.getDesafioAt(0).inicia(new Imagem(this,this.getCodeBase(),IMAGE_CHECK));
    		return true;
    	}
    	return false;
    	    	
    }
    
    public void novoJogo(){    	
    	this.firstTime = true;
    	this.contaValida = 0;    	
    	this.getDesafioAtivo().setAtivo(false);
    	eventos = new Evento[NUM_EVENTOS];
    	desafios = new Vector();    	
    	super.atualiza();  	
    }
    
    public void limpar(){    	
    	Evento evento;
    	for(int i=0;i<this.getDesafioAtivo().getNivelAtual().qntEventos();i++){
    		evento = this.getDesafioAtivo().getNivelAtual().getEventoAt(i);    		
    		evento.getConjunto().limpa();    		
    	}
    	
    	Quadrado quadrado;
    	for(int i=0;i<this.getDesafioAtivo().getNivelAtual().qntQuadrados();i++){
    		quadrado = this.getDesafioAtivo().getNivelAtual().getQuadrado(i);
    		for(int j=0;j<quadrado.qntMarcadores();j++)
    			quadrado.getMarcador(j).setMarcado(false);    		
    	}
    	
    	super.atualiza();
    }
    
    public String proximo(){
    	try{
	    	if(this.getDesafioAtivo().proximoNivel(new Imagem(this,this.getCodeBase(),IMAGE_CHECK))==null){
	    		if(this.proximoDesafio()){					
					
					this.atualiza();
					return(this.getDesafioAtivo().getNivelAtual().getMensagemInicial());
				}else{										
					getAppletContext().showDocument(new URL("javascript:fim();"));
					this.atualiza();
					return("Parabens, você venceu todos os desafios!!");
				}
	    	}else{
	    		
				this.atualiza();
				return(this.getDesafioAtivo().getNivelAtual().getMensagemInicial());
	    	}
	    		
    	}catch (Exception e) {
			e.printStackTrace();
		}
    	return "";
    }
    
    public int validarMarcacao(){
    	contaValida++;
    	int contaErros = 0;
    	boolean errou = false;
    	
    	Desafio ativo = this.getDesafioAtivo();
    	   	
		try{
			if(ativo.isCompleto()){
				errou = true;
				//if(this.proximoDesafio()){
				//	this.printMsg(this.getDesafioAtivo().getNivelAtual().getMensagemInicial());
				//	getAppletContext().showDocument(new URL("javascript:construirLegenda();"));
				//}else{					
				//	this.printMsg("Parabens, você venceu todos os desafios!!");
				//	getAppletContext().showDocument(new URL("javascript:fim();"));
				//}
			}else{
				//this.printMsg(this.getDesafioAtivo().getNivelAtual().getMensagemInicial());
				//getAppletContext().showDocument(new URL("javascript:construirLegenda();"));
			}
			
		}catch(Exception e){
			errou = true;			
			System.out.println(e.getMessage());
		}    		
		
		if(errou){
			if(contaValida>MAX_ERROS){
				for(int i=0;i<ativo.getNivelAtual().qntEventos();i++){
					contaErros += ativo.getNivelAtual().setMostrandoErros();				
				}			
			
				for(int i=0;i<ativo.getNivelAtual().qntOperacoes();i++){
					contaErros += ativo.getNivelAtual().setMostrandoErros();
				}	
			}else{
				for(int i=0;i<ativo.getNivelAtual().qntEventos();i++){
					contaErros += ativo.getNivelAtual().getEventoAt(i).getConjunto().contaErro();
				}			
			
				for(int i=0;i<ativo.getNivelAtual().qntOperacoes();i++){
					contaErros += ativo.getNivelAtual().getOperacaoAt(i).getConjunto().contaErro();
				}	
			}						
		}
    	atualiza();
    	return contaErros;
    }
	
	private void printMsg(String msg){
		try{
			getAppletContext().showDocument(new URL("javascript:printMsg('"+msg+"');"));		
			
		}catch (Exception e) {			
		}
	}
    
    public boolean isCompleto(){
    	return this.getDesafioAtivo().getNivelAtual().isCompleto();    	
    }

/**
 * <p>Realiza marcacao dos quadrados, forma os pares ordenados e verifica se clicou na legenda.</p>
 */
    public void doOnClick(Point click) {
    	boolean atualiza = false;
        for(int i=0;i<this.getDesafioAtivo().getNivelAtual().qntQuadrados();i++){
            if(this.getDesafioAtivo().getNivelAtual().getQuadrado(i).checkClick(click)){
                for(int j=0;j<this.getDesafioAtivo().getNivelAtual().getQuadrado(i).qntMarcadores();j++){
                    if(this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getMarcador(j).checkClick(click)){
                       
                    	this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getMarcador(j).alteraMarcacao();
                        
                        if(this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getMarcador(j).isMarcado())
                        	this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getMarcador(j).getEvento().getConjunto().addParOrdenado(this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getCoordenadas(),new Color(106,143,0),new Color(110,168,234));
                        else
                        	this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getMarcador(j).getEvento().getConjunto().removeParOrdenado(this.getDesafioAtivo().getNivelAtual().getQuadrado(i).getCoordenadas());
                        
                        atualiza = true;                            
                    
                    }
                }
            }
        }
        
       
        if(atualiza)
        	super.atualiza();
    } 
    
    
    private void criaEventos(){   	
    	eventos[0] = new Evento(new Legenda("Soma maior que 8","Soma menor ou igual a 8",Color.cyan)){

			public boolean isValido(Point coordenada){
					return (coordenada.x+1+coordenada.y+1)>8;				
			}

    	};
    	
    	eventos[1] = new Evento(new Legenda("Menor face igual a 5","Menor face diferente a 5",Color.cyan)){

    		public boolean isValido(Point coordenada){    			
				return Math.min(coordenada.x+1, coordenada.y+1)==5;
    		}
    		

    	};
    	
    	eventos[2] = new Evento(new Legenda("Face par no primeiro dado","Face impar no primeiro dado",Color.cyan)){

    		public boolean isValido(Point coordenada){
				return ((coordenada.y+1)%2)==0;		
    		}
	
    	};
    	
    	eventos[3] = new Evento(new Legenda("Soma igual a 6","Soma diferente a 6",Color.cyan)){

    		public boolean isValido(Point coordenada){
				return (coordenada.x+1+coordenada.y+1)==6;		
    		}
	
    	};
    	
    	eventos[4] = new Evento(new Legenda("Produto das faces maior que 15","Produto das faces menor ou igual a 15",Color.cyan)){

    		public boolean isValido(Point coordenada){
				return ((coordenada.x+1)*(coordenada.y+1))>15;		
    		}
	
    	};
    	
    	eventos[5] = new Evento(new Legenda("Número primo no segundo dado","Número não primo no segundo dado.",Color.cyan)){

    		public boolean isValido(Point coordenada){
				return isPrimo((coordenada.x+1));		
    		}
	
    	};
    	
    	eventos[6] = new Evento(new Legenda("Maior face maior que 4","Maior face menor ou igual a 4",Color.cyan)){

    		public boolean isValido(Point coordenada){
				return Math.max(coordenada.x+1, coordenada.y+1)>4;	
    		}
	
    	};
    	   	    
    	
    	
    }
    
    private boolean isPrimo(int num){
    	if(num==1)return false;
    	for(int i=2;i<num;i++){
    		if(num%i==0)return false;
    	}
    	return true;
    }
          
    
    @Override
	public void desenha(Graphics g){
    	Color oldColor = g.getColor();
    	g.setColor(Color.white);
    	g.fillRect(super.posicao.x, super.posicao.y, ESPACO_COLUNAS*(this.numColunas), ESPACO_LINHAS*(this.numLinhas));
    	g.setColor(oldColor);
    	g.drawRect(super.posicao.x, super.posicao.y, ESPACO_COLUNAS*(this.numColunas), ESPACO_LINHAS*(this.numLinhas));
    	
    	
    	Imagem dice;
    	//Desenha Numeros das Colunas
    	for(int i=0;i<numColunas;i++){
    		dice = new Imagem(this,this.getCodeBase(),IMAGE_DICE+"_X_"+(i+1)+".gif"); 
    		mediaTracker.addImage(dice.getImagem(), i);
    		g.drawImage(dice.getImagem(), super.posicao.x+(ESPACO_COLUNAS-dice.getWidth())/2 + (ESPACO_COLUNAS*i), super.posicao.y-dice.getHeight(),dice.getObserver());
    	}
    	
    	//Desenha Numeros das Linhas    	
    	for(int i=0;i<numLinhas;i++){
    		dice = new Imagem(this,this.getCodeBase(),IMAGE_DICE+"_Y_"+(i+1)+".gif");    
    		mediaTracker.addImage(dice.getImagem(), i);
    		g.drawImage(dice.getImagem(), super.posicao.x-dice.getWidth()-2, super.posicao.y+(ESPACO_LINHAS-dice.getHeight())/2 + (ESPACO_LINHAS*i),dice.getObserver());
    	}
    	
    	//Desenha quadrados
    	/*for(int i=0;i<this.quadrados.size();i++)
    		this.getQuadrado(i).desenha(g);*/
    	getDesafioAtivo().getNivelAtual().desenha(g);
    	
    	
    	int ultimaLinha = -1;
    	/*for(int i=0;i<QNT_EVENTOS;i++){ 
    		ultimaLinha = this.desenhaConjunto(g, this.getSorteioAt(i), ultimaLinha);
    	}    	
    	
    	for(int i=0;i<QNT_OPERACOES;i++){
    		ultimaLinha = this.desenhaConjunto(g, this.getOperacaoAt(i), ultimaLinha);
    	}*/
    	
    }
    

	@Override
	public void init() {		
		this.addMouseListener(this);
		super.setDefaultAttributes();
		this.numColunas=6;
		this.numLinhas= 6;
		super.posicao = new Point(40,34);
		super.setDoubleBuffered(true);	
	}

	@Override
	public void paint(Graphics g) {
		try{
			
			mediaTracker = new MediaTracker(this);
			
			if(firstTime){
													
				
				criaEventos();
				criaDesafios();
				proximoDesafio();				
				firstTime = false;
				this.printMsg(this.getDesafioAtivo().getNivelAtual().getMensagemInicial());				
				getAppletContext().showDocument(new URL("javascript:done();"));
			}			
			this.desenha(g);			
			mediaTracker.waitForAll();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public int getOperacaoAt(int index){
		//System.out.println("GetOperandoAt: "+(NUM_EVENTOS-QNT_OPERACOES+index));
		return index;
	}

	public void mouseClicked(MouseEvent e) {
		if(e.isShiftDown()){						
			this.atualiza();
		}else
			this.doOnClick(e.getPoint());
		
	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseReleased(MouseEvent e) {
	}
	
	public boolean hasComplemento(){
		return this.getDesafioAtivo().getNivelAtual().hasComplemento();
	}
	
	public String conjuntoNome(int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntEventos()){
			return String.valueOf(this.getDesafioAtivo().getNivelAtual().getEventoAt(index).getConjunto().getNome());
		}else
			return "eof";
	}
	
	public String legendaDescricao(int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntEventos()){
			return this.getDesafioAtivo().getNivelAtual().getEventoAt(index).getLegenda().getDescricao();		
		}else
			return "eof";
	}
	
	public String legendaDescricaoOperacao(int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntOperacoes()){		
			return this.getDesafioAtivo().getNivelAtual().getOperacaoAt(index).getLegenda().getDescricao();
		}else
			return "eof";
	}
	
	public String expressaoOperacao(int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntOperacoes()){		
			return this.getDesafioAtivo().getNivelAtual().getOperacaoAt(index).getExpressao();
		}else
			return "eof";
	}
	
	public String conjuntoNomeOperacao(int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntOperacoes()){			
			return String.valueOf(this.getDesafioAtivo().getNivelAtual().getOperacaoAt(index).getConjunto().getNome());
		}else
			return "eof";
	}
	
	
	
	public String getOperacaoDescricao(int index){
		int formato = this.getDesafioAtivo().getNivelAtual().getFormato();
		if(formato == Nivel.FORMATO_EXPRESSAO)
			return expressaoOperacao(index);
		else if(formato == Nivel.FORMATO_DESCRICAO)
			return legendaDescricaoOperacao(index);
		
		return "eof";
	}
	
	public boolean isExpressao(int index){
		return this.getDesafioAtivo().getNivelAtual().getFormato()==Nivel.FORMATO_EXPRESSAO;
	}
	
	public boolean perguntaExpressao(){
		return this.getDesafioAtivo().getNivelAtual().isPerguntaExpressao();
	}
	
	public void respondeProbabilidade(int numerador, int denominador,int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntProbabilidades())
			this.getDesafioAtivo().getNivelAtual().getProbabilidadeAt(index).valida(numerador+"/"+denominador);
	}
	
	public boolean hasProbabilidade(){
		//JOptionPane.showMessageDialog(null, this.getDesafioAtivo().getNivelAtual().qntProbabilidades()+" prob");
		return this.getDesafioAtivo().getNivelAtual().qntProbabilidades()>0;
	}
	
	public boolean hasEvento(){
		//JOptionPane.showMessageDialog(null, this.getDesafioAtivo().getNivelAtual().qntOperacoes()+" ope");
		return this.getDesafioAtivo().getNivelAtual().qntOperacoes()>0;
	}
	
	public boolean hasMontaOperacao(){
		return this.getDesafioAtivo().getNivelAtual().isPerguntaExpressao();
	}
	
	public String getExpressaoProbabilidade(int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntProbabilidades()){
			Evento evento = this.getDesafioAtivo().getNivelAtual().getProbabilidadeAt(index).getEvento();
			if (evento instanceof Operacao) {
				return String.valueOf(((Operacao)evento).getExpressao());
			}else{	
				String comp="";
				if(this.getDesafioAtivo().getNivelAtual().getProbabilidadeAt(index).isComplemento())
					comp="|";
				return comp+evento.getConjunto().getNome();				
			}
		}
		return "eof";
	}
	
	public boolean hasLoad(){
		return !this.firstTime;
	}

	public int getNumLinhas() {
		return numLinhas;
	}

	public void setNumLinhas(int numLinhas) {
		this.numLinhas = numLinhas;
	}

	public int getNumColunas() {
		return numColunas;
	}

	public void setNumColunas(int numColunas) {
		this.numColunas = numColunas;
	}
	
	public Desafio getDesafioAt(int i){
		return (Desafio)this.desafios.get(i);
	}
	
	public boolean isMostrandoErros(){
		return contaValida>MAX_ERROS;
	}
	
	public String desafioMensagem(){
		return this.getDesafioAtivo().getMensagemInicial();
	}
	
	public void respondeExpressao(String expressao,int index){
		if(index<this.getDesafioAtivo().getNivelAtual().qntOperacoes()){
			JOptionPane.showMessageDialog(null, this.getDesafioAtivo().getNivelAtual().getOperacaoAt(index).getExpressao());
			this.getDesafioAtivo().getNivelAtual().getOperacaoAt(index).respondeExpressao(expressao);
		}
	}
		
 }
